
package cn.backflow.admin.controller;

import cn.backflow.admin.common.pagination.Page;
import cn.backflow.admin.common.pagination.PageRequest;
import cn.backflow.admin.controller.base.BaseSpringController;
import cn.backflow.admin.entity.Version;
import cn.backflow.admin.entity.VersionUser;
import cn.backflow.admin.service.VersionService;
import cn.backflow.lib.util.JsonMap;
import cn.backflow.admin.common.secure.Permissions;;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

@RestController
@RequestMapping("version")
public class VersionController extends BaseSpringController {
    protected static final String DEFAULT_SORT_COLUMNS = "id desc"; // 默认多列排序,example: username desc,created asc

    @Autowired
    private VersionService versionService;


    /* 列表 */
    @Permissions("version.view")
    public Object index(Version version, HttpServletRequest request) throws Exception {
        JsonMap json = JsonMap.succeed();
        PageRequest pr = pageRequest(request, DEFAULT_SORT_COLUMNS);

        String updatePolicy = request.getParameter("updatePolicy");

        if ("updateByUser".equals(updatePolicy)) {
            pr.getFilters().put("updateByUser", 1);
        } else if ("updateByPercent".equals(updatePolicy)) {
            pr.getFilters().put("updateByPercent", 1);
        } else if ("forceUpdate".equals(updatePolicy)) {
            pr.getFilters().put("forceUpdate", 1);
        }

        Page<Version> page = versionService.findPage(pr);
        toJsonMap(page, pr, json);
        return "version/list";
    }

    /* 显示 */

    @Permissions("version.view")
    public Object byId(@PathVariable Integer id, HttpServletRequest request) throws Exception {
        JsonMap json = JsonMap.succeed();
        Version version = versionService.getById(id);
        json.put("version", version);
        return "version/form";
    }


    /* 编辑 */
    @Permissions("version.view")
    public String edit(@PathVariable Integer id, HttpServletRequest request) throws Exception {
        JsonMap json = JsonMap.succeed();
        // 当前要编辑的版本
        Version version = versionService.getById(id);
        // 所有状态正常的渠道
        // 当前版本已关联的渠道

        /* 构建页面展示控件需要的json数据结构 */
        buildSelectizeSelectedOptions(id, json);

        json.put("version", version);
        return "version/form";
    }

    /**
     * 构建selectize.js需要的数据结果
     *
     * @param versionId 版本ID
     */
    private void buildSelectizeSelectedOptions(Integer versionId, JsonMap json) {

        // 当前版本关联的所有用户, 无论是白名单或是黑名单
        List<VersionUser> versionUsers = versionService.findVersionUsers(versionId);
        if (versionUsers.isEmpty()) return;
        // 白名单用户ID列表
        List<Integer> whiteUserIds = new ArrayList<>();
        // 黑名单用户ID列表
        List<Integer> blackUserIds = new ArrayList<>();
        for (VersionUser vu : versionUsers) {
            if (vu.getType() == 0)
                whiteUserIds.add(vu.getUserId());
            else
                blackUserIds.add(vu.getUserId());
        }
        // 合并ID列表一并查询
        List<Integer> allUserIds = new ArrayList<>();
        allUserIds.addAll(whiteUserIds);
        allUserIds.addAll(blackUserIds);

        List<Map<String, Object>> userMaps = versionService.searchUsers(null, allUserIds);

        List<JSONObject> whiteUsers = new ArrayList<>(); // 白名单用户json数据
        List<JSONObject> blackUsers = new ArrayList<>(); // 黑名单用户json数据

        for (Map<String, Object> map : userMaps) {
            Integer id = (Integer) map.get("id");
            if (whiteUserIds.contains(id)) {
                whiteUsers.add(new JSONObject(map));
            } else {
                blackUsers.add(new JSONObject(map));
            }
        }
        json.put("whiteUsers", whiteUsers);
        json.put("blackUsers", blackUsers);
    }


    /* 保存新增 */

    @Permissions("version.edit")
    public Object create(@Valid Version version, BindingResult errors, HttpServletRequest request)
            throws Exception {
        JsonMap json = JsonMap.succeed();
        if (errors.hasErrors()) {
            return filedErrors(errors, json);
        }
        persistWithUsersAndChannels(version, request);
        return json;
    }

    private void persistWithUsersAndChannels(Version version, HttpServletRequest request) {
        String[] channels = request.getParameterValues("channels");
        String[] whiteUsers = request.getParameterValues("whiteUsers");
        String[] blackUsers = request.getParameterValues("blackUsers");
        versionService.persistWithUsersAndChannels(version, whiteUsers, blackUsers, channels);
    }

    /* 保存更新 */

    @Permissions("version.edit")
    public Object update(@PathVariable Integer id, @Valid Version version, BindingResult errors, HttpServletRequest request) throws Exception {
        JsonMap json = JsonMap.succeed();
        if (errors.hasErrors()) {
            return filedErrors(errors, json);
        }
        persistWithUsersAndChannels(version, request);
        return json;
    }


    @RequestMapping("search_users/{keyword}")
    public Object searchUsers(@PathVariable("keyword") String keyword) {
        return versionService.searchUsers(keyword, null);
    }

    /* 删除 */

    @Permissions("version.del")
    public Object delete(@PathVariable Integer id, HttpServletRequest request) {
        versionService.deleteById(id);
        return JsonMap.succeed();
    }

    /* 批量删除 */

    @Permissions("version.del")
    public Object delete(@RequestParam("items") Set<Integer> items, HttpServletRequest request) {
        versionService.deleteBatch(items);
        return JsonMap.succeed();
    }
}